<template>
  <div class="bodys">
    <!-- 顶部部分 -->
    <div class="topStyle">
      <div>{{ time }}</div>
      <div>{{ title }}</div>
      <div>福建宁德 星期二 晴 31-36℃</div>
    </div>
    <!-- 主体部分 -->
    <div class="mainStyle">
      <!-- 左边数据表格 -->
      <div>
        <dv-border-box-1>
          <div>各地工厂产量</div>
          <Proportion />
          <!-- <div id="container01"></div> -->
        </dv-border-box-1>
        <dv-border-box-1>
          <div>综合分析统计图</div>
          <div id="container02"></div>
        </dv-border-box-1>
        <dv-border-box-1>
          <div>生成车型</div>
          <div id="container03"></div>
        </dv-border-box-1>
      </div>
      <!-- 中间部分 -->
      <div>
        <!-- 地图 -->
        <div>
          <div id="containerMap" style="width: 100%; height: 100%"></div>
        </div>
        <!-- 三维跑车模型 -->
        <div>
          <div id="modelCar"></div>
        </div>
      </div>
      <!-- 右边数据表格 -->
      <div>
        <dv-border-box-1>
          <div>实时销量</div>
          <div id="container04"></div>
        </dv-border-box-1>
        <dv-border-box-1>
          <div>车型销量占比</div>
          <div id="container05"></div>
        </dv-border-box-1>
        <dv-border-box-1>
          <div>历史销量</div>
          <div id="container06"></div>
        </dv-border-box-1>
      </div>
    </div>
  </div>
</template>

<script>
import * as g2plot from "@antv/g2plot";
// import * as l7plot from '@antv/l7plot';
import * as THREE from "three";

import { GLTFLoader } from "three/examples/jsm/loaders/GLTFLoader";
import { OrbitControls } from "three/examples/jsm/controls/OrbitControls";
import { getCurrentTime } from "@/utils/tools";
import Proportion from "./echarts/Proportion.vue";
export default {
  name: "DemoOne",
  components: { Proportion },
  data() {
    return {
      time: "",
      CurrentTimer: null,
      // 页面标题
      title: "宁德时代可视化大屏",
      // 场景
      scene: null,
      // 环境光
      ambienLight: null,
      // 加载的场景
      loaderScene: null,
      // 渲染器
      renderer: null,
      // 相机
      camera: null,
    };
  },
  mounted() {
    // console.log("getCurrentTime", getCurrentTime());
    this.CurrentTimer = setInterval(() => {
      this.time = getCurrentTime();
    }, 1000);
    // 地图加载
    this.loadMap();
    // 跑车模型加载
    this.init();
    // 数据表格加载
    setTimeout(() => {
      this.loadContainer01();
      this.loadContainer02();
      this.loadContainer03();
      this.loadContainer04();
      this.loadContainer05();
      this.loadContainer06();
    }, 500);
  },
  destroyed() {
    this.CurrentTimer = null;
    clearInterval(this.CurrentTimer);
  },
  methods: {
    clearScene() {
      if (this.scene) {
        this.scene.traverse(function (v) {
          if (v.type === "Mesh") {
            v.geometry.dispose();
            v.material.dispose();
          }
        });
        while (this.scene.children.length > 0) {
          this.scene.remove(this.scene.children[0]);
        }
        this.renderer.dispose();
        this.renderer.forceContextLoss();
        this.renderer.domElement = null;
        this.renderer = null;
        this.scene.clear();
        this.scene = null;
        this.camera = null;
        this.ambienLight = null;
        this.loaderScene = null;
      }
    },
    init() {
      this.clearScene();
      this.scene = new THREE.Scene();
      this.ambienLight = new THREE.AmbientLight("#ffffff", 1);
      this.scene.add(this.ambienLight);
      let loader = new GLTFLoader();
      loader.load("../gltf/scene.gltf", (gltf) => {
        let boundingBox = new THREE.Box3().setFromObject(gltf.scene);
        let boundingBoxCenter = new THREE.Vector3();
        boundingBox.getCenter(boundingBoxCenter);
        const width = document.getElementById("modelCar").clientWidth;
        const height = document.getElementById("modelCar").clientHeight;
        this.camera = new THREE.PerspectiveCamera(45, width / height, 1, 10000);
        let sceneSize = new THREE.Vector3();
        boundingBox.getSize(sceneSize);
        this.sceneMeshHeight = sceneSize.y;
        this.sceneMeshWidth = sceneSize.x;
        let distance =
          Math.max(sceneSize.x, sceneSize.y, sceneSize.z) /
          2 /
          Math.tan(((this.camera.fov / 2) * Math.PI) / 180);
        this.camera.position.set(distance / 2.5, sceneSize.y, distance / 2.5);
        this.camera.lookAt(0, 0, 0);
        this.renderer = new THREE.WebGLRenderer({ alpha: true });
        this.renderer.setSize(width, height);
        document
          .getElementById("modelCar")
          .appendChild(this.renderer.domElement);
        this.renderer.outputEncoding = THREE.sRGBEncoding;
        this.control = new OrbitControls(this.camera, this.renderer.domElement);
        this.control.zoomSpeed = 0.5;
        this.control.enableDamping = true;
        this.control.dampingFactor = 0.02;
        this.control.minPolarAngle = 0;
        this.control.maxPolarAngle = 1.5;
        let envMap = new THREE.CubeTextureLoader().load([
          "/sky/st/posx.jpg",
          "/sky/st/negx.jpg",
          "/sky/st/posy.jpg",
          "/sky/st/negy.jpg",
          "/sky/st/posz.jpg",
          "/sky/st/negz.jpg",
        ]);
        gltf.scene.traverse(function (item) {
          if (item instanceof THREE.Mesh) {
            item.material.envMap = envMap;
            item.material.envMapIntensity = 1;
            item.material.needsUpdate = true;
          }
        });
        this.scene.add(gltf.scene);
        this.loaderScene = gltf.scene;
        this.animat();
        this.autoCanvas();
      });
    },
    animat() {
      if (this.loaderScene != null) {
        this.loaderScene.rotateY(0.01);
      }
      this.renderer.render(this.scene, this.camera);
      this.control.update();
      requestAnimationFrame(this.animat);
    },
    autoCanvas() {
      let app = this;
      window.onresize = function () {
        app.renderer.setSize(window.innerWidth, window.innerHeight);
        app.camera.aspect = window.innerWidth / window.innerHeight;
        app.camera.updateProjectionMatrix();
      };
    },
    loadMap() {
      fetch(
        "https://gw.alipayobjects.com/os/alisis/geo-data-v0.1.2/administrative-data/area-list.json"
      )
        .then((response) => response.json())
        .then((list) => {
          const data = list
            .filter(({ level }) => level === "district")
            .map((item) =>
              Object.assign({}, item, { value: Math.random() * 5000 })
            );
          new l7plot.Choropleth("containerMap", {
            map: {
              type: "map",
              center: [120.19382669582967, 30.258134],
              zoom: 3,
              pitch: 0,
            },
            source: {
              data: data,
              joinBy: {
                sourceField: "adcode",
                geoField: "adcode",
              },
            },
            viewLevel: {
              level: "province",
              adcode: 430000,
              granularity: "district",
            },
            autoFit: true,
            color: {
              field: "value",
              value: ["#B8E1FF", "#7DAAFF", "#3D76DD", "#0047A5", "#001D70"],
              scale: { type: "quantize" },
            },
            style: {
              opacity: 1,
              stroke: "#ccc",
              lineWidth: 0.6,
              lineOpacity: 1,
            },
            label: {
              visible: true,
              field: "name",
              style: {
                fill: "#fff",
                opacity: 0.8,
                fontSize: 10,
                stroke: "#000",
                strokeWidth: 1.5,
                textAllowOverlap: false,
                padding: [5, 5],
              },
            },
            state: {
              active: { stroke: "black", lineWidth: 1 },
            },
            tooltip: {
              items: ["name", "adcode", "value"],
            },
          });
        });
    },
    loadContainer06() {
      fetch(
        "https://gw.alipayobjects.com/os/bmw-prod/b21e7336-0b3e-486c-9070-612ede49284e.json"
      )
        .then((res) => res.json())
        .then((data) => {
          const area = new g2plot.Area("container06", {
            data,
            xField: "date",
            yField: "value",
            seriesField: "country",
            slider: {
              start: 0.1,
              end: 0.9,
              textStyle: {
                fill: "#fff",
              },
            },
            xAxis: {
              label: {
                style: {
                  fill: "#fff",
                },
              },
            },
            yAxis: {
              label: {
                style: {
                  fill: "#fff",
                },
              },
            },
            legend: {
              itemName: {
                style: {
                  fill: "#fff",
                },
              },
            },
          });
          area.render();
        });
    },
    loadContainer05() {
      const data = [
        { type: "奥迪", value: 27 },
        { type: "宝马", value: 25 },
        { type: "奔驰", value: 18 },
        { type: "五菱", value: 15 },
        { type: "大众", value: 10 },
        { type: "其他", value: 5 },
      ];

      const piePlot = new g2plot.Pie("container05", {
        appendPadding: 10,
        data,
        legend: {
          itemName: {
            style: {
              fill: "#fff",
            },
          },
        },
        angleField: "value",
        colorField: "type",
        radius: 0.9,
        label: {
          type: "inner",
          offset: "-30%",
          content: ({ percent }) => `${(percent * 100).toFixed(0)}%`,
          style: {
            fontSize: 14,
            textAlign: "center",
          },
        },
        interactions: [
          { type: "element-active" },
          { type: "element-selected" },
        ],
      });

      piePlot.render();
      // 如果业务中还有单选联动，可以考虑使用按住某个键来区分交互 (或者多选之后，让用户自己去触发查询)
      document.addEventListener("keyup", (evt) => {
        if (evt.key === "Shift") {
          console.info(evt);
          const states = piePlot.getStates();
          console.info(states.filter((d) => d.state === "selected"));
          // 获取选中元素
          // states.filter(d => d.state === 'selected')
        }
      });
    },
    loadContainer04() {
      fetch(
        "https://gw.alipayobjects.com/os/antfincdn/mor%26R5yBI9/stack-group-column.json"
      )
        .then((data) => data.json())
        .then((data) => {
          const column = new g2plot.Column("container04", {
            data,
            xField: "product_type",
            yField: "order_amt",
            isGroup: true,
            isStack: true,
            seriesField: "product_sub_type",
            groupField: "sex",
            xAxis: {
              label: {
                style: {
                  fill: "#fff",
                },
              },
            },
            yAxis: {
              label: {
                style: {
                  fill: "#fff",
                },
              },
            },
            legend: {
              itemName: {
                style: {
                  fill: "#fff",
                },
              },
            },
          });

          column.render();
        });
    },
    loadContainer03() {
      fetch(
        "https://gw.alipayobjects.com/os/antvdemo/assets/data/antv-keywords.json"
      )
        .then((res) => res.json())
        .then((data) => {
          const wordCloud = new g2plot.WordCloud("container03", {
            data,
            wordField: "name",
            weightField: "value",
            colorField: "name",
            wordStyle: {
              fontFamily: "Verdana",
              fontSize: [8, 32],
              rotation: 0,
            },
            random: () => 0.5,
          });

          wordCloud.render();
        });
    },
    loadContainer02() {
      const averageData = [
        { date: "2015-02", value: 21168 },
        { date: "2015-08", value: 21781 },
        { date: "2016-01", value: 23818 },
        { date: "2017-02", value: 25316 },
        { date: "2018-01", value: 26698 },
        { date: "2018-08", value: 27890 },
      ];

      const plot = new g2plot.Mix("container02", {
        appendPadding: 8,
        tooltip: { shared: true },
        syncViewPadding: true,
        plots: [
          {
            type: "column",
            options: {
              data: [
                { date: "2015-02", value: 160 },
                { date: "2015-08", value: 245 },
                { date: "2016-01", value: 487 },
                { date: "2017-02", value: 500 },
                { date: "2018-01", value: 503 },
                { date: "2018-08", value: 514 },
              ],
              xField: "date",
              yField: "value",
              yAxis: {
                type: "log",
                max: 100000,
                label: {
                  style: {
                    fill: "#fff",
                  },
                },
              },
              meta: {
                date: {
                  sync: true,
                },
                value: {
                  alias: "店数(间)",
                },
              },
              label: {
                position: "middle",
                style: {
                  fill: "#fff",
                },
              },
            },
          },
          {
            type: "line",
            options: {
              data: averageData,
              xField: "date",
              yField: "value",
              xAxis: false,
              yAxis: {
                type: "log",
                max: 100000,
                label: {
                  style: {
                    fill: "#fff",
                  },
                },
              },
              label: {
                offsetY: -8,
                style: {
                  fill: "#fff",
                },
              },
              meta: {
                value: {
                  alias: "平均租金(元)",
                },
              },
              color: "#FF6B3B",
              annotations: averageData.map((d) => {
                return {
                  type: "dataMarker",
                  position: d,
                  point: {
                    style: {
                      stroke: "#FF6B3B",
                      lineWidth: 1.5,
                    },
                  },
                };
              }),
            },
          },
          {
            type: "line",
            options: {
              data: [
                { date: "2015-02", value: null },
                { date: "2015-08", value: 0.029 },
                { date: "2016-01", value: 0.094 },
                { date: "2017-02", value: 0.148 },
                { date: "2018-01", value: 0.055 },
                { date: "2018-08", value: 0.045 },
              ],
              xField: "date",
              yField: "value",
              xAxis: {
                label: {
                  style: {
                    fill: "#fff",
                  },
                },
              },
              yAxis: {
                line: null,
                grid: null,
                position: "right",
                max: 0.16,
                tickCount: 8,
                label: {
                  style: {
                    fill: "#fff",
                  },
                },
              },
              meta: {
                date: {
                  sync: "date",
                },
                value: {
                  alias: "递增",
                  formatter: (v) => `${(v * 100).toFixed(1)}%`,
                },
              },
              smooth: true,
              label: {
                callback: (value) => {
                  return {
                    offsetY: value === 0.148 ? 36 : value === 0.055 ? 0 : 20,
                    style: {
                      fill: "#1AAF8B",
                      fontWeight: 700,
                      stroke: "#fff",
                      lineWidth: 1,
                    },
                  };
                },
              },
              color: "#1AAF8B",
            },
          },
        ],
      });

      plot.render();
    },
    loadContainer01() {
      fetch(
        "https://gw.alipayobjects.com/os/antfincdn/PC3daFYjNw/column-data.json"
      )
        .then((data) => data.json())
        .then((data) => {
          const column = new g2plot.Column("container01", {
            data,
            xField: "city",
            yField: "value",
            seriesField: "type",
            isGroup: "true",
            columnStyle: {
              radius: [20, 20, 0, 0],
            },
            xAxis: {
              label: {
                style: {
                  fill: "#fff",
                },
              },
            },
            yAxis: {
              label: {
                style: {
                  fill: "#fff",
                },
              },
            },
            legend: {
              itemName: {
                style: {
                  fill: "#fff",
                },
              },
            },
          });

          column.render();
        });
    },
  },
};
</script>

<style lang="scss" scoped>
.mainStyle {
  color: #ffffff;
  margin: 2% 5%;
  height: 85%;
  display: flex;
  > div:nth-child(1),
  div:nth-child(3) {
    width: 25%;
    > div {
      width: 100%;
      height: 30%;
      margin: 4% 0;
      > div {
        > div {
          display: flex;
          justify-content: center;
          width: 94%;
          margin: 0 3%;
        }
        > div:nth-child(1) {
          padding-top: 2%;
          font-size: 20px;
          font-family: "FZY4JW";
          color: #35f3fd;
        }
        > div:nth-child(2) {
          height: 79%;
        }
      }
    }
  }
  > div:nth-child(2) {
    width: 50%;
    > div {
      padding: 0 2%;
    }
    > div:nth-child(1) {
      margin-top: 1%;
      height: 58%;
      > div > div {
        position: absolute;
        top: 2.5%;
        height: 95% !important;
      }
    }
    > div:nth-child(2) {
      margin-top: 1%;
      height: 35%;
      > div {
        width: 100%;
        height: 100%;
      }
    }
  }
}

.topStyle {
  color: #fff;
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin: 1.6% 6% 0 6%;
  font-size: 18px;
  > div:nth-child(2) {
    font-size: 32px;
    font-family: "FZZiYHJW";
    letter-spacing: 3px;
    margin-left: 4%;
  }
}

.bodys {
  overflow: hidden;
  width: 100vw;
  height: 100vh;
  background-image: url("../assets/background.png");
  background-size: 100% 100%;
}

@font-face {
  font-family: "FZZiYHJW";
  src: url("../assets/font/FZZiYHJW.TTF");
  // src: url('@/assets/font/FZZiYHJW.TTF');
}

@font-face {
  font-family: "FZY4JW";
  src: url("../assets/font/FZY4JW.TTF");
  // src: url('@/assets/font/FZY4JW.TTF');
}
</style>
